home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / tracker-4.13.lha / tracker / st_play.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-15  |  10.2 KB  |  427 lines

  1. /* st_play.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: st_play.c,v 4.9 1995/02/14 04:02:28 espie Exp $
  6.  * $Log: st_play.c,v $
  7.  * Revision 4.9  1995/02/14  04:02:28  espie
  8.  * Suppressed comment.
  9.  *
  10.  * Revision 4.9  1995/02/14  04:02:28  espie
  11.  * Suppressed comment.
  12.  *
  13.  * Revision 4.8  1995/02/06  14:50:47  espie
  14.  * Changed sample_info.
  15.  *
  16.  * Revision 4.8  1995/02/06  14:50:47  espie
  17.  * Changed sample_info.
  18.  *
  19.  * Revision 4.7  1995/02/01  20:41:45  espie
  20.  * Added color.
  21.  *
  22.  * Revision 4.6  1995/02/01  16:39:04  espie
  23.  * Left/Right channels.
  24.  *
  25.  * Revision 4.6  1995/02/01  16:39:04  espie
  26.  * Left/Right channels.
  27.  *
  28.  * Revision 4.5  1995/02/01  15:31:25  espie
  29.  * *** empty log message ***
  30.  *
  31.  * Revision 4.4  1995/01/28  09:23:59  espie
  32.  * *** empty log message ***
  33.  *
  34.  * Revision 4.3  1994/11/15  16:11:01  espie
  35.  * *** empty log message ***
  36.  *
  37.  * Revision 4.3  1994/11/15  16:11:01  espie
  38.  * *** empty log message ***
  39.  *
  40.  *
  41.  * Revision 4.0  1994/01/11  17:51:40  espie
  42.  * Use the new UI calls.
  43.  * Use the new pref settings.
  44.  *
  45.  * Revision 1.14  1994/01/09  23:24:37  Espie
  46.  * Last bug fix.
  47.  * Suppressed really outdated code.
  48.  * New names: new_channel_tag_list, release_audio_channel.
  49.  * Some notice to status.
  50.  * Use new pref scheme.
  51.  * Use get_ui
  52.  * Use autoinit feature of display.c
  53.  * discard_buffer forgotten...
  54.  * Handle errors better.
  55.  *
  56.  * Revision 3.18  1993/12/04  16:12:50  espie
  57.  * Lots of changes.
  58.  * New high-level functions.
  59.  * Amiga support.
  60.  * Bug with delay_pattern: can't factorize the check for effect thingy.
  61.  * Reniced verbose output display.
  62.  * Bug fix: now use correct finetune when loading samples/starting notes.
  63.  * Added bg/fg test.
  64.  * General cleanup
  65.  * Added <> operators.
  66.  * Added update frequency on the fly.
  67.  * Added finetune.
  68.  * Protracker commands.
  69.  *
  70.  * Revision 2.19  1992/11/17  17:15:37  espie
  71.  * Added interface using may_getchar(). Still primitive, though.
  72.  * imask, start.
  73.  * Added transpose feature.
  74.  * Added possibility to get back to MONO for the sgi.
  75.  * Added stereo capabilities to the indigo version.
  76.  * Added two level of fault tolerancy.
  77.  * Added some control on the number of replays,
  78.  * and better error recovery.
  79.  */
  80.      
  81. #include "defs.h"
  82. #include "song.h"
  83. #include "channel.h"
  84. #include "extern.h"
  85. #include "tags.h"
  86. #include "prefs.h"
  87.      
  88.  
  89. ID("$Id: st_play.c,v 4.9 1995/02/14 04:02:28 espie Exp $")
  90.      
  91.  
  92. /* setting up a given note */
  93.  
  94. void reset_note(ch, note, pitch)
  95. struct channel *ch;
  96. int note;
  97. int pitch;
  98.    {
  99.    ch->pitch = pitch;
  100.    ch->note = note;
  101.    ch->viboffset = 0;
  102.    play_note(ch->audio, ch->samp, pitch);
  103.    }
  104.  
  105. /* changing the current pitch (value
  106.  * may be temporary, and not stored
  107.  * in channel pitch, for instance vibratos.
  108.  */
  109. void set_current_pitch(ch, pitch)
  110. struct channel *ch;
  111. int pitch;
  112.    {
  113.       /* save current pitch in case we want to change
  114.        * the step table on the run
  115.    ch->cpitch = pitch;
  116.    ch->step = step_table[pitch];
  117.       */
  118.    set_play_pitch(ch->audio, pitch);
  119.    }
  120.  
  121. /* changing the current volume. You HAVE to get through
  122.  * there so that it will work on EVERY machine.
  123.  */
  124. void set_current_volume(ch, volume)
  125. struct channel *ch;
  126. int volume;
  127.    {
  128.    ch->volume = MAX(MIN(volume, MAX_VOLUME), MIN_VOLUME);
  129.    set_play_volume(ch->audio, ch->volume);
  130.    }
  131.  
  132. void set_position(ch, pos)
  133. struct channel *ch;
  134. int pos;
  135.    {
  136.    set_play_position(ch->audio, pos);
  137.    }
  138.  
  139. /* init_channel(ch, dummy):
  140.  * setup channel, with initially
  141.  * a dummy sample ready to play,
  142.  * and no note.
  143.  */
  144. LOCAL void init_channel(ch, side)
  145. struct channel *ch;
  146. int side;
  147.    {
  148.     struct tag tags[2];
  149.     tags[0].type = AUDIO_SIDE;
  150.     tags[0].data.scalar = side;
  151.     tags[1].type = TAG_END;
  152.    ch->samp = empty_sample();
  153.    ch->finetune = 0;
  154.    ch->audio = new_channel_tag_list(tags);
  155.    ch->volume = 0; 
  156.    ch->pitch = 0; 
  157.    ch->note = NO_NOTE;
  158.  
  159.       /* we don't setup arpeggio values. */
  160.    ch->viboffset = 0; 
  161.    ch->vibdepth = 0;
  162.  
  163.    ch->slide = 0; 
  164.  
  165.    ch->pitchgoal = 0; 
  166.    ch->pitchrate = 0;
  167.  
  168.    ch->volumerate = 0;
  169.  
  170.    ch->vibrate = 0;
  171.    ch->adjust = do_nothing;
  172.    }
  173.  
  174.  
  175.  
  176. LOCAL int VSYNC;          /* base number of sample to output */
  177. LOCAL void (*eval[NUMBER_EFFECTS]) P((struct automaton *a, struct channel *ch));
  178.                     /* the effect table */
  179. LOCAL int oversample;     /* oversample value */
  180. LOCAL int frequency;      /* output frequency */
  181.  
  182. LOCAL struct channel chan[NUMBER_TRACKS];
  183.                     /* every channel */
  184.  
  185. LOCAL struct sample_info **voices;
  186.  
  187. LOCAL struct automaton a;
  188.  
  189.  
  190. void init_player(o, f)
  191. int o, f;
  192.    {
  193.    oversample = o;
  194.    frequency = f;
  195.    init_tables(o, f);
  196.    init_effects(eval);
  197.    }
  198.  
  199. LOCAL void setup_effect(ch, a, e)
  200. struct channel *ch;
  201. struct automaton *a;
  202. struct event *e;
  203.    {
  204.    int samp, cmd;
  205.  
  206.       /* retrieves all the parameters */
  207.    samp = e->sample_number;
  208.  
  209.       /* load new instrument */
  210.    if (samp)  
  211.       {
  212.          /* note that we can change sample in the middle
  213.           * of a note. This is a *feature*, not a bug (see
  214.           * made). Precisely: the sample change will be taken
  215.           * into account for the next note, BUT the volume change
  216.           * takes effect immediately.
  217.           */
  218.       ch->samp = voices[samp];
  219.         ch->finetune = voices[samp]->finetune;
  220.         if ((1L<<samp) & get_pref_scalar(PREF_IMASK))
  221.             ch->samp = empty_sample();
  222.         set_current_volume(ch, voices[samp]->volume);
  223.       }
  224.  
  225.    a->note = e->note;
  226.    if (a->note != NO_NOTE)
  227.       a->pitch = pitch_table[a->note][ch->finetune];
  228.    else
  229.       a->pitch = e->pitch;
  230.    cmd = e->effect;
  231.    a->para = e->parameters;
  232.  
  233.    if (a->pitch >= REAL_MAX_PITCH)
  234.       {
  235.       char buffer[60];
  236.       sprintf(buffer,"Pitch out of bounds %d", a->pitch);
  237.       status(buffer);
  238.       a->pitch = 0;
  239.       error = FAULT;
  240.       }
  241.  
  242.       /* check for a new note: portamento
  243.        * is the special case where we do not restart
  244.        * the note.
  245.        */
  246.    if (a->pitch && cmd != EFF_PORTA && cmd != EFF_PORTASLIDE)
  247.       reset_note(ch, a->note, a->pitch);
  248.    ch->adjust = do_nothing;
  249.       /* do effects */
  250.    (eval[cmd])(a, ch);
  251.    }
  252.  
  253.  
  254. LOCAL void adjust_sync(ofreq, tempo)
  255. int ofreq, tempo;
  256.    {
  257.    VSYNC = ofreq * NORMAL_FINESPEED / tempo;
  258.    }
  259.  
  260. LOCAL void play_once(a)
  261. struct automaton *a;
  262.    {
  263.    int channel;
  264.  
  265.    if (a->do_stuff & DELAY_PATTERN)
  266.       for (channel = 0; channel < NUMBER_TRACKS; channel++)
  267.          /* do the effects */
  268.          (chan[channel].adjust)(chan + channel);
  269.    else
  270.       {  
  271.       if (a->counter == 0)
  272.          {
  273.          for (channel = 0; channel < NUMBER_TRACKS; channel++)
  274.             /* setup effects */
  275.             setup_effect(chan + channel, a, 
  276.                &(a->pattern->e[channel][a->note_num]));
  277.             if (get_pref_scalar(PREF_SHOW))
  278.                 {
  279.                     /* display the output in a reasonable order:
  280.                      * LEFT1 LEFT2 || RIGHT1 RIGHT 2
  281.                      */
  282.                 dump_event(chan, &(a->pattern->e[0][a->note_num]));
  283.                 dump_event(chan+3, &(a->pattern->e[3][a->note_num]));
  284.                 dump_delimiter();
  285.                 dump_event(chan+1, &(a->pattern->e[1][a->note_num]));
  286.                 dump_event(chan+2, &(a->pattern->e[2][a->note_num]));
  287.                 dump_event(0, 0);
  288.                 }
  289.          }
  290.       else
  291.          for (channel = 0; channel < NUMBER_TRACKS; channel++)
  292.             /* do the effects */
  293.             (chan[channel].adjust)(chan + channel);
  294.       }
  295.  
  296.       /* advance player for the next tick */
  297.    next_tick(a);
  298.       /* actually output samples */
  299.    resample(oversample, VSYNC / a->finespeed);
  300.    }
  301.  
  302. LOCAL struct tag pres[2];
  303.  
  304.  
  305. struct tag *play_song(song, start)
  306. struct song *song;
  307. int start;
  308.    {
  309.    int tempo;
  310.    int countdown;      /* keep playing the tune or not */
  311.  
  312.    song_title(song->title);
  313.    pres[1].type = TAG_END;
  314.    
  315.    tempo = get_pref_scalar(PREF_SPEED);
  316.  
  317.    adjust_sync(frequency, tempo);
  318.     /* a repeats of 0 is infinite replays */
  319.    
  320.    countdown = get_pref_scalar(PREF_REPEATS);
  321.    if (countdown == 0)
  322.       countdown = 50000;   /* ridiculously huge number */
  323.  
  324.    voices = song->samples; 
  325.  
  326.    init_automaton(&a, song, start);
  327.  
  328.    release_audio_channels();
  329.  
  330.     init_channel(chan, LEFT_SIDE);
  331.     init_channel(chan + 1, RIGHT_SIDE);
  332.     init_channel(chan + 2, RIGHT_SIDE);
  333.     init_channel(chan + 3, LEFT_SIDE);
  334.  
  335.    while(countdown)
  336.       {
  337.       struct tag *result;
  338.       
  339.       play_once(&a);
  340.       result = get_ui();
  341.       while(result = get_tag(result))
  342.          {
  343.          switch(result->type)
  344.             {  
  345.          case UI_LOAD_SONG:
  346.             if (!result->data.pointer)
  347.                break;
  348.          case UI_NEXT_SONG:
  349.          case UI_PREVIOUS_SONG:
  350.             discard_buffer();
  351.             pres[0].type = result->type;
  352.             pres[0].data = result->data;
  353.             return pres;
  354.          case UI_QUIT:
  355.             discard_buffer();
  356.             end_all(0);
  357.             /* NOTREACHED */
  358.          case UI_SET_BPM:
  359.             tempo = result->data.scalar;
  360.             adjust_sync(frequency, tempo);
  361.             break;
  362.          case UI_RESTART:
  363.             discard_buffer();
  364.             init_automaton(&a, song, start);
  365.             release_audio_channels();
  366.                     init_channel(chan, LEFT_SIDE);
  367.                     init_channel(chan + 1, RIGHT_SIDE);
  368.                     init_channel(chan + 2, RIGHT_SIDE);
  369.                     init_channel(chan + 3, LEFT_SIDE);
  370.             break;
  371.          case UI_JUMP_TO_PATTERN:
  372.             if (result->data.scalar >= 0 && result->data.scalar < a.info->length)
  373.                {
  374.                discard_buffer();
  375.                init_automaton(&a, song, result->data.scalar);
  376.                }
  377.             break;
  378.             /*
  379.          case ' ':
  380.             while (may_getchar() == EOF)
  381.                ;
  382.             break;
  383.              */
  384.          default:
  385.             break;
  386.             }
  387.          result++;
  388.          }
  389.  
  390.       {
  391.       int new_freq;
  392.       if (new_freq = update_frequency())
  393.          {
  394.          frequency = new_freq;
  395.          adjust_sync(frequency, tempo);
  396.          init_tables(oversample, frequency);
  397.          }
  398.       }
  399.  
  400.       switch(error)
  401.          {
  402.       case NONE:
  403.          break;
  404.       case ENDED:
  405.          countdown--;
  406.          break;
  407.       case SAMPLE_FAULT:
  408.       case FAULT:
  409.       case PREVIOUS_SONG:
  410.       case NEXT_SONG:
  411.       case UNRECOVERABLE:
  412.          if ( (error == SAMPLE_FAULT && get_pref_scalar(PREF_TOLERATE))
  413.             ||(error == FAULT && get_pref_scalar(PREF_TOLERATE) > 1) )
  414.             break;
  415.          pres[0].type = PLAY_ERROR;
  416.          pres[0].data.scalar = error;
  417.          return pres;
  418.       default:
  419.          break;
  420.          }
  421.          error = NONE;
  422.       }
  423.    pres[0].type = TAG_IGNORE;      
  424.    return pres;
  425.    }
  426.  
  427.